<?php

namespace  App\Dao\Mongo;

use App\Models\Mongo\Server\File as FileMongo;
// use App\Models\Mongo\Server\FileCommon as FileMongo;
use MongoDB\BSON\ObjectId;
use App\Services\Settings\Server as SettingsServer;
use MongoDB\BSON\Regex;
class FileSlice extends BaseMongo
{

    public static function create(string $admins_id, int $is_common)
    {
        //0代表非公共 1代表公共
        return $is_common === 0 ? FileMongo::create(substr($admins_id, 0, 1)) : FileMongo::create('common');
    }

    public static function insertOne(string $admins_id, int $is_common, int $dir_id, int $slice_size, array $file_list)
    {
        $create_time  = time();
        return FileMongo::create($admins_id)->insertMany(array_map(function ($item) use ($is_common, $slice_size, $dir_id, $create_time) {
            $arr = [];
            $arr['is_common'] = $is_common;
            $arr['dir_id'] = $dir_id;
            $arr['create_time'] = $create_time;
            $arr['file_name'] = $item['file_name'];
            $arr['file_type'] = $item['file_type'];
            $arr['size'] = $item['size'];
            $arr['slice_size'] = $slice_size;
            $arr['is_complete'] = 0;          //是否上传完成
            $arr['slice_num'] = ceil($item['size'] / 1024 / $slice_size);  //切片次数
            return $arr;
        }, $file_list));
    }

    public static function insert(string $admins_id, int $is_common, array $params)
    {
        return self::create($admins_id, $is_common)->insertOne(
            [
                'dir_id'    =>    $params['dir_id'],       //文件夹id
                'file_size' =>    $params['file_size'],    //文件大小
                'admins_id' =>    $params['admins_id'],
                'file_url'  =>    $params['file_url'],
                'schedule'  =>    0,                       //文件上传进度
                'file_type' =>    $params['file_type'],
                'file_name' =>    $params['file_name'],
                'dir_link' =>    $params['dir_link'],
                'create_time' =>  time(),
                'is_del' => 0,  //是否再回收站
                'wait_del' => 0 , // 是否在队列等待删除
                'update_time' => time()
            ]
        )->getInsertedId()->__toString();
    }

    public static function list(string $admins_id, int $is_common, string $dir_link, int $pageNum, int $pageSize, string $keyWord,array $file_type)
    {
        $arr = [];

        $filter  = self::configList($admins_id, $dir_link , $keyWord , $file_type) ;

        $settings =  SettingsServer::dev()->getItem(['prefix_url']);

        // https://lwl-study.oss-cn-guangzhou.aliyuncs.com/

        foreach (self::create($admins_id, $is_common)->find($filter,[
            "sort" => [
                "create_time" => -1
            ],
              'projection' => [
                "file_size" => 1,
                "file_name" => 1,
                "create_time" => 1,
                "schedule" => 1,
                'file_type' => 1,
                "full_url" =>   ['$concat' => [$settings['prefix_url'] , '$file_url' ]],
                "_id" => [
                    '$toString' =>  '$_id'
                ]
              ],
            "skip" => ($pageNum - 1) * $pageSize,
            "limit" => $pageSize
        ]) as $val){

            $arr[] = (array) $val;
        }
        return $arr;
    }

    public static function total(string $admins_id, int $is_common, string $dir_link, string $keyWord, array $file_type)
    {
        $filter  = self::configList($admins_id, $dir_link, $keyWord, $file_type);

        return self::create($admins_id, $is_common)->countDocuments($filter);
    }

    public static function oidFinds(string $admins_id, int $is_common , array $oids){
        $array = [];
        foreach(  self::create($admins_id, $is_common)->find(['$and' => [
            ['admins_id' =>  $admins_id],
            ['$or' => array_map(fn ($item) => ['_id' => new ObjectId($item)] , $oids) ]
        ]])  as $item ){
            $array[] = (array)$item;
        };

        return $array;
    }

    public static function oidFindOne(string $admins_id, int $is_common , string $oid){

        return self::create($admins_id, $is_common)->findOne(['$and' => [
            ['admins_id' =>  $admins_id],
            [ '_id' => new ObjectId($oid)]
        ]]) ;
    }

    public static function configList(string $admins_id,string $dir_link,string $keyWord,array $file_type){
        $filter  = [  '$and' => [
              ['admins_id' =>  $admins_id ],
              ['$or' => [ ['wait_del'  => ['$exists' => false]] , ['wait_del' => 0] ]]
         ] ];

        if($dir_link === '-1'){
            //软删除
            $filter['$and'][] = ['is_del' => 1];
        }else{
            //没有被删除
            $filter['$and'][] = ['$or' => [ ['is_del'  => ['$exists' => false]] , ['is_del' => 0] ]];

            //文件夹
            if ($dir_link !== '0')  $filter['$and'][] = ['dir_link' => new Regex('^' . $dir_link)] ;

        }


        if ( $keyWord ) $filter['$and'][] =  [ 'file_name' => new Regex('^' . $keyWord) ];

        if (!empty($file_type)){
            $filter['$and'][] = ['$or' => array_map(function($item){
                return ['file_type' => $item];
            },$file_type) ];
        }


        return $filter;
    }

    // 当前容量
    public static function capacity(string $admins_id, int $is_common){

        $cursor =  self::create($admins_id, $is_common)->aggregate([
            [ '$match' => [ "admins_id" => $admins_id , 'wait_del' => 0  ] ],
            [ '$group'=>  [ "_id" => null, 'capacity' => [ '$sum' => '$file_size' ] ] ]
        ]);

        $cursor = iterator_to_array($cursor);

        return count($cursor) > 0 ?  $cursor[0]->capacity : 0;  //统计当前积累的容量
    }


    public static function schedule(string $admins_id, int $is_common, array $params)
    {
        return self::create($admins_id, $is_common)->updateOne(['admins_id' => $admins_id, '_id' => new ObjectId($params['oid'])], ['$set' => ['update_time' => time(), 'schedule' => $params['schedule']]]);
    }


    public static function del(string $admins_id, int $is_common ,array $oids){
        return  self::create($admins_id, $is_common)->deleteMany([
            '$and' => [
                ['admins_id' =>  $admins_id],
                ['$or' => array_map( function($item) {
                   return [ '_id' => new ObjectId($item) ];
                }, $oids)  ]
            ]
        ]) ;
    }

    public static function update(string $admins_id, int $is_common, array $oids, array $update){

        return  self::create($admins_id, $is_common)->updateMany([
            '$and' => [
                ['admins_id' =>  $admins_id],
                ['$or' => array_map(function ($item) {
                    return ['_id' => new ObjectId($item)];
                }, $oids)]
            ]
        ], ['$set' => $update]);
    }

}
